<?php

/**
 * This class is based around the sfAutoConfigPlugin from
 *
 * http://www.symfony-project.org/plugins/sfAutoconfigPlugin
 *
 * by Mathias Vitalis
 *
 * Implementing the same basic concept but a slightly different way
 *
 */
class distributionConfigureinstanceTask extends sfBaseTask {
    protected function configure() {

        $this->addArguments(array(
                new sfCommandArgument('distribution-file', sfCommandArgument::REQUIRED, 'The YAML file with variables to substitute'),
                new sfCommandArgument('defaults-file',
                sfCommandArgument::OPTIONAL,
                'A file with default variable values',
                sfConfig::get('sf_config_dir').DIRECTORY_SEPARATOR.'dist'.DIRECTORY_SEPARATOR.'defaults.yml')
        ));


// add your own options here
// $this->addOptions(array(
//          new sfCommandOption('distribution-file', null, sfCommandOption::PARAMETER_REQUIRED, 'The YAML file with variables to substitute')
//  ));

        $this->namespace        = 'distribution';
        $this->name             = 'configure';
        $this->briefDescription = 'Configure an instance of the software for distrribution or after an update';
        $this->detailedDescription = <<<EOF
The [distribution:configure-instance|INFO] task does things.
Call it with:

  [php symfony distribution:configure-instance|INFO]
EOF;
    }

    protected function execute($arguments = array(), $options = array()) {

        $substitutionVariables = array();

        try {
            if (file_exists($arguments['distribution-file'])) {
                $substitutionVariables = sfYaml::load($arguments['distribution-file']);
                $substitutionVariables['distribution'] = $this->cleanSubstitutionVariables($substitutionVariables['distribution']);
                if ($substitutionVariables != null) {
                    $this->logSection('configure','Distribution File '.$arguments['distribution-file'].' - Loaded','INFO');
                } else {
                    $this->logSection('configure','Error Parsing Distribution File ('.$arguments['distribution-file'].')', 'ERROR');
                }
            } else {
                $this->logSection('configure','Distribution File '.$arguments['distribution-file'].' - Not Found ', 'ERROR');

            }
        } catch(Exception $e) {
            $this->logSection('configure','Error Parsing Distribution File '.$arguments['distribution-file'].'', 'ERROR');
            return;
        }

        $defaultVariables = array();

        try {
            if (file_exists($arguments['defaults-file'])) {
                $defaultVariables = sfYaml::load($arguments['defaults-file']);
                $defaultVariables['distribution'] = $this->cleanSubstitutionVariables($defaultVariables['distribution']);
                if ($defaultVariables != null) {
                    $this->logSection('configure','Defaults File '.$arguments['defaults-file'].' - Loaded','INFO');
                } else {
                    $this->logSection('configure','Error Parsing Defaults File '.$arguments['defaults-file'].'', 'ERROR');
                }
            } else {
                $this->logSection('configure','Defaults File '.$arguments['defaults-file'].' - Not Found ', 'ERROR');

            }
        } catch(Exception $e) {
            $this->logSection('configure','Error Parsing Defaults File '.$arguments['defaults-file'].'', 'ERROR');
            return;
        }

        /**
         * yaml file must not be empty
         */


        $this->logSection('configure', 'Searching: '.sfConfig::get('sf_root_dir'));

        $finder = new sfFinder();
        $finder->name('*-dist.*');
        $finder->type('file');
        /**
         * Exclude directories which probably shouldn't have distribution
         * files in them
         */
        $finder->prune(DIRECTORY_SEPARATOR.'lib');
        $finder->prune(DIRECTORY_SEPARATOR.'log');
        $finder->prune(DIRECTORY_SEPARATOR.'cache');
        $finder->prune(DIRECTORY_SEPARATOR.'plugins');
        $baseFiles = $finder->in(sfConfig::get('sf_root_dir'));

        if (count($baseFiles) > 0) {
            $this->logSection('process', 'Processing Files');

            foreach ($baseFiles as $baseFilename) {
                $this->logSection('process', $baseFilename);
                //Remove the -dist from the filename for the distribution file
                $distFilename = preg_replace('/(.*)-dist/','$1',$baseFilename);
                //use the filesytem object to copy the file ove
                $this->getFilesystem()->copy($baseFilename, $distFilename, array('override' => true));
                /**
                 * If there is no distribution section don't try and substitute variables
                 */
                //Substitute the variables
                if(array_key_exists('distribution', $substitutionVariables)) {
                    $this->getFilesystem()->replaceTokens(array($distFilename), '<%', '%>', $substitutionVariables['distribution']);
                } else {
                    $this->logSection('configure', 'Distribution File empty - no tokens processed');
                }

                //Substitute any remaining variables with defaults
                //i.e. any which are not specifically overridden by the user
                //will be left and be set by the defaults file
                if(array_key_exists('distribution', $defaultVariables)) {
                    $this->getFilesystem()->replaceTokens(array($distFilename), '<%', '%>', $defaultVariables['distribution']);
                } else {
                    $this->logSection('configure', 'Defaults File empty - no tokens processed');
                }


            }
        } else {
            $this->logSection('process', 'No files to process');
        }
    }

    public function cleanSubstitutionVariables(array $substitutionVariables) {
        return   preg_replace('/(?<!\\\\)\\\\(?!\\\\)/','',$substitutionVariables);;
    }
}
